﻿using System;
using System.Linq;
using HslCommunication.BasicFramework;
using HslCommunication.Core;
using HslCommunication.Reflection;
using HslCommunication.Serial;

namespace HslCommunication.Profinet.Omron
{
	/// <summary>
	/// 欧姆龙的HostLink协议的实现，地址支持示例 DM区:D100; CIO区:C100; Work区:W100; Holding区:H100; Auxiliary区: A100<br />
	/// Implementation of Omron's HostLink protocol, address support example DM area: D100; CIO area: C100; Work area: W100; Holding area: H100; Auxiliary area: A100
	/// </summary>
	/// <remarks>
	/// 感谢 深圳～拾忆 的测试，地址可以携带站号信息，例如 s=2;D100 
	/// <br />
	/// <note type="important">
	/// 如果发现串口线和usb同时打开才能通信的情况，需要按照如下的操作：<br />
	/// 串口线不是标准的串口线，电脑的串口线的235引脚分别接PLC的329引脚，45线短接，就可以通讯，感谢 深圳-小君(QQ932507362)提供的解决方案。
	/// </note>
	/// </remarks>
	/// <example>
	/// <inheritdoc cref="T:HslCommunication.Profinet.Omron.OmronHostLinkOverTcp" path="example" />
	/// </example>
	// Token: 0x0200005F RID: 95
	public class OmronHostLink : SerialDeviceBase
	{
		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronFinsNet.#ctor" />
		// Token: 0x060007DA RID: 2010 RVA: 0x0002A038 File Offset: 0x00028238
		public OmronHostLink()
		{
			base.ByteTransform = new ReverseWordTransform();
			base.WordLength = 1;
			base.ByteTransform.DataFormat = DataFormat.CDAB;
			base.ByteTransform.IsStringReverseByteWord = true;
		}

		/// <inheritdoc cref="P:HslCommunication.Profinet.Omron.OmronHostLinkOverTcp.ICF" />
		// Token: 0x1700016A RID: 362
		// (get) Token: 0x060007DB RID: 2011 RVA: 0x0002A098 File Offset: 0x00028298
		// (set) Token: 0x060007DC RID: 2012 RVA: 0x0002A0A0 File Offset: 0x000282A0
		public byte ICF { get; set; } = 0;

		/// <inheritdoc cref="P:HslCommunication.Profinet.Omron.OmronHostLinkOverTcp.DA2" />
		// Token: 0x1700016B RID: 363
		// (get) Token: 0x060007DD RID: 2013 RVA: 0x0002A0A9 File Offset: 0x000282A9
		// (set) Token: 0x060007DE RID: 2014 RVA: 0x0002A0B1 File Offset: 0x000282B1
		public byte DA2 { get; set; } = 0;

		/// <inheritdoc cref="P:HslCommunication.Profinet.Omron.OmronHostLinkOverTcp.SA2" />
		// Token: 0x1700016C RID: 364
		// (get) Token: 0x060007DF RID: 2015 RVA: 0x0002A0BA File Offset: 0x000282BA
		// (set) Token: 0x060007E0 RID: 2016 RVA: 0x0002A0C2 File Offset: 0x000282C2
		public byte SA2 { get; set; }

		/// <inheritdoc cref="P:HslCommunication.Profinet.Omron.OmronHostLinkOverTcp.SID" />
		// Token: 0x1700016D RID: 365
		// (get) Token: 0x060007E1 RID: 2017 RVA: 0x0002A0CB File Offset: 0x000282CB
		// (set) Token: 0x060007E2 RID: 2018 RVA: 0x0002A0D3 File Offset: 0x000282D3
		public byte SID { get; set; } = 0;

		/// <inheritdoc cref="P:HslCommunication.Profinet.Omron.OmronHostLinkOverTcp.ResponseWaitTime" />
		// Token: 0x1700016E RID: 366
		// (get) Token: 0x060007E3 RID: 2019 RVA: 0x0002A0DC File Offset: 0x000282DC
		// (set) Token: 0x060007E4 RID: 2020 RVA: 0x0002A0E4 File Offset: 0x000282E4
		public byte ResponseWaitTime { get; set; } = 48;

		/// <inheritdoc cref="P:HslCommunication.Profinet.Omron.OmronHostLinkOverTcp.UnitNumber" />
		// Token: 0x1700016F RID: 367
		// (get) Token: 0x060007E5 RID: 2021 RVA: 0x0002A0ED File Offset: 0x000282ED
		// (set) Token: 0x060007E6 RID: 2022 RVA: 0x0002A0F5 File Offset: 0x000282F5
		public byte UnitNumber { get; set; }

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronFinsNet.Read(System.String,System.UInt16)" />
		// Token: 0x060007E7 RID: 2023 RVA: 0x0002A100 File Offset: 0x00028300
		[HslMqttApi("ReadByteArray", "")]
		public override OperateResult<byte[]> Read(string address, ushort length)
		{
			byte station = (byte)HslHelper.ExtractParameter(ref address, "s", (int)this.UnitNumber);
			OperateResult<byte[]> operateResult = OmronFinsNetHelper.BuildReadCommand(address, length, false);
			bool flag = !operateResult.IsSuccess;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				OperateResult<byte[]> operateResult2 = base.ReadBase(this.PackCommand(station, operateResult.Content));
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<byte[]>(operateResult2);
				}
				else
				{
					OperateResult<byte[]> operateResult3 = OmronHostLinkOverTcp.ResponseValidAnalysis(operateResult2.Content, true);
					bool flag3 = !operateResult3.IsSuccess;
					if (flag3)
					{
						result = OperateResult.CreateFailedResult<byte[]>(operateResult3);
					}
					else
					{
						result = OperateResult.CreateSuccessResult<byte[]>(operateResult3.Content);
					}
				}
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronFinsNet.Write(System.String,System.Byte[])" />
		// Token: 0x060007E8 RID: 2024 RVA: 0x0002A1A4 File Offset: 0x000283A4
		[HslMqttApi("WriteByteArray", "")]
		public override OperateResult Write(string address, byte[] value)
		{
			byte station = (byte)HslHelper.ExtractParameter(ref address, "s", (int)this.UnitNumber);
			OperateResult<byte[]> operateResult = OmronFinsNetHelper.BuildWriteWordCommand(address, value, false);
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				OperateResult<byte[]> operateResult2 = base.ReadBase(this.PackCommand(station, operateResult.Content));
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = operateResult2;
				}
				else
				{
					OperateResult<byte[]> operateResult3 = OmronHostLinkOverTcp.ResponseValidAnalysis(operateResult2.Content, false);
					bool flag3 = !operateResult3.IsSuccess;
					if (flag3)
					{
						result = operateResult3;
					}
					else
					{
						result = OperateResult.CreateSuccessResult();
					}
				}
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronFinsNet.ReadBool(System.String,System.UInt16)" />
		// Token: 0x060007E9 RID: 2025 RVA: 0x0002A238 File Offset: 0x00028438
		[HslMqttApi("ReadBoolArray", "")]
		public override OperateResult<bool[]> ReadBool(string address, ushort length)
		{
			byte station = (byte)HslHelper.ExtractParameter(ref address, "s", (int)this.UnitNumber);
			OperateResult<byte[]> operateResult = OmronFinsNetHelper.BuildReadCommand(address, length, true);
			bool flag = !operateResult.IsSuccess;
			OperateResult<bool[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<bool[]>(operateResult);
			}
			else
			{
				OperateResult<byte[]> operateResult2 = base.ReadBase(this.PackCommand(station, operateResult.Content));
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<bool[]>(operateResult2);
				}
				else
				{
					OperateResult<byte[]> operateResult3 = OmronHostLinkOverTcp.ResponseValidAnalysis(operateResult2.Content, true);
					bool flag3 = !operateResult3.IsSuccess;
					if (flag3)
					{
						result = OperateResult.CreateFailedResult<bool[]>(operateResult3);
					}
					else
					{
						result = OperateResult.CreateSuccessResult<bool[]>(Enumerable.ToArray<bool>(Enumerable.Select<byte, bool>(operateResult3.Content, (byte m) => m != 0)));
					}
				}
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronFinsNet.Write(System.String,System.Boolean[])" />
		// Token: 0x060007EA RID: 2026 RVA: 0x0002A30C File Offset: 0x0002850C
		[HslMqttApi("WriteBoolArray", "")]
		public override OperateResult Write(string address, bool[] values)
		{
			byte station = (byte)HslHelper.ExtractParameter(ref address, "s", (int)this.UnitNumber);
			OperateResult<byte[]> operateResult = OmronFinsNetHelper.BuildWriteWordCommand(address, Enumerable.ToArray<byte>(Enumerable.Select<bool, byte>(values, (bool m) => m ? 1 : 0)), true);
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				OperateResult<byte[]> operateResult2 = base.ReadBase(this.PackCommand(station, operateResult.Content));
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = operateResult2;
				}
				else
				{
					OperateResult<byte[]> operateResult3 = OmronHostLinkOverTcp.ResponseValidAnalysis(operateResult2.Content, false);
					bool flag3 = !operateResult3.IsSuccess;
					if (flag3)
					{
						result = operateResult3;
					}
					else
					{
						result = OperateResult.CreateSuccessResult();
					}
				}
			}
			return result;
		}

		/// <inheritdoc />
		// Token: 0x060007EB RID: 2027 RVA: 0x0002A3C9 File Offset: 0x000285C9
		public override string ToString()
		{
			return string.Format("OmronHostLink[{0}:{1}]", base.PortName, base.BaudRate);
		}

		/// <summary>
		/// 将普通的指令打包成完整的指令
		/// </summary>
		/// <param name="station">PLC的站号信息</param>
		/// <param name="cmd">fins指令</param>
		/// <returns>完整的质量</returns>
		// Token: 0x060007EC RID: 2028 RVA: 0x0002A3E8 File Offset: 0x000285E8
		private byte[] PackCommand(byte station, byte[] cmd)
		{
			cmd = SoftBasic.BytesToAsciiBytes(cmd);
			byte[] array = new byte[18 + cmd.Length];
			array[0] = 64;
			array[1] = SoftBasic.BuildAsciiBytesFrom(station)[0];
			array[2] = SoftBasic.BuildAsciiBytesFrom(station)[1];
			array[3] = 70;
			array[4] = 65;
			array[5] = this.ResponseWaitTime;
			array[6] = SoftBasic.BuildAsciiBytesFrom(this.ICF)[0];
			array[7] = SoftBasic.BuildAsciiBytesFrom(this.ICF)[1];
			array[8] = SoftBasic.BuildAsciiBytesFrom(this.DA2)[0];
			array[9] = SoftBasic.BuildAsciiBytesFrom(this.DA2)[1];
			array[10] = SoftBasic.BuildAsciiBytesFrom(this.SA2)[0];
			array[11] = SoftBasic.BuildAsciiBytesFrom(this.SA2)[1];
			array[12] = SoftBasic.BuildAsciiBytesFrom(this.SID)[0];
			array[13] = SoftBasic.BuildAsciiBytesFrom(this.SID)[1];
			array[array.Length - 2] = 42;
			array[array.Length - 1] = 13;
			cmd.CopyTo(array, 14);
			int num = (int)array[0];
			for (int i = 1; i < array.Length - 4; i++)
			{
				num ^= (int)array[i];
			}
			array[array.Length - 4] = SoftBasic.BuildAsciiBytesFrom((byte)num)[0];
			array[array.Length - 3] = SoftBasic.BuildAsciiBytesFrom((byte)num)[1];
			return array;
		}
	}
}
